package com.zmn.oms.zmn.business.impl.docking;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.zmn.base.channel.common.dro.ChannelDRO;
import com.zmn.base.channel.dubbo.interfaces.channel.ChannelListRemoteService;
import com.zmn.base.common.data.dubbo.interfaces.area.AreaListRemoteService;
import com.zmn.base.engineer.common.dro.foreign.engineer.ForeignEngineerBasicInfoDRO;
import com.zmn.base.engineer.dubbo.interfaces.foreign.EngineerListRemoteService;
import com.zmn.base.oms.common.model.es.orderwork.EsOrderWork;
import com.zmn.base.product.common.dto.product.ProductBaseQuery;
import com.zmn.base.product.common.dto.product.ec.ProductBaseDRO;
import com.zmn.base.product.dubbo.interfaces.product.foreign.ProductForeignListRemoteService;
import com.zmn.common.constant.GlobalConsts;
import com.zmn.common.constant.StatusConsts;
import com.zmn.common.dto2.ResponseDTO;
import com.zmn.common.utils.collection.CollectionUtil;
import com.zmn.common.utils.date.DateUtil;
import com.zmn.common.utils.math.MathUtil;
import com.zmn.common.utils.math.MoneyUtil;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.common.utils.reflect.BeanMapper;
import com.zmn.common.utils.string.StringUtil;
import com.zmn.consts.GateTypeConsts;
import com.zmn.log.client.user.operation.AddUserOperationLogRequest;
import com.zmn.log.client.user.operation.UserOperationLogClient;
import com.zmn.log.client.user.operation.item.DeviceLogItem;
import com.zmn.log.client.user.operation.item.EntryLogItem;
import com.zmn.log.client.user.operation.item.event.AddOrderEventLogItem;
import com.zmn.manager.redis.lock.DistributedLock;
import com.zmn.manager.redis.lock.DistributedLockUtils;
import com.zmn.mos.common.dio.order.add.ChannelApiOrderAddDIO;
import com.zmn.mos.common.dio.order.add.nest.ChannelApiExtraData;
import com.zmn.mos.common.dio.order.add.nest.OrderBaseInfo;
import com.zmn.mos.common.dio.order.add.nest.OrderProductDIO;
import com.zmn.mos.common.dio.order.add.nest.UserDIO;
import com.zmn.mos.common.dro.order.OrderAddDRO;
import com.zmn.mos.dubbo.interfaces.order.ChannelApiOrderRemoteService;
import com.zmn.oms.business.interfaces.comment.OrderCommentBService;
import com.zmn.oms.business.interfaces.discount.OrderDiscountBService;
import com.zmn.oms.business.interfaces.log.OrderLogBService;
import com.zmn.oms.business.interfaces.order.DuplicateOrderBService;
import com.zmn.oms.business.interfaces.remark.OrderRemarkBService;
import com.zmn.oms.business.interfaces.servtype.ServItemBService;
import com.zmn.oms.business.interfaces.track.OrderTrackBService;
import com.zmn.oms.business.interfaces.work.OrderWorkAmountBService;
import com.zmn.oms.common.constant.*;
import com.zmn.oms.common.dto.OmsBaseOperator;
import com.zmn.oms.common.exception.OmsBaseException;
import com.zmn.oms.common.utils.FilterUtil;
import com.zmn.oms.model.bo.order.OrderBO;
import com.zmn.oms.model.dto.comment.OrderCommentDTO;
import com.zmn.oms.model.dto.discount.AddDiscountDTO;
import com.zmn.oms.model.dto.order.open.AvailableTimeslotsQuery;
import com.zmn.oms.model.dto.order.proxy.*;
import com.zmn.oms.model.dto.serviceitem.GetServiceItemDTO;
import com.zmn.oms.model.dto.track.OrderTrackDTO;
import com.zmn.oms.model.dto.track.OrderTrackDetailDTO;
import com.zmn.oms.model.dto.work.modify.CheckQuotationTypeOrderDTO;
import com.zmn.oms.model.dto.work.modify.ServiceItemQueryDTO;
import com.zmn.oms.model.dto.work.modify.ServiceItemResultDTO;
import com.zmn.oms.model.dto.work.modify.amount.ZsUpdateChannelPrepayAmountDTO;
import com.zmn.oms.model.dto.work.modify.must.ZsCancelDTO;
import com.zmn.oms.model.dto.work.modify.must.ZsOrderPayDTO;
import com.zmn.oms.model.dto.work.workamount.ValidateWorkAmountDTO;
import com.zmn.oms.model.entity.detail.OrderDetail;
import com.zmn.oms.model.entity.log.OrderLog;
import com.zmn.oms.model.entity.order.OrderExtend;
import com.zmn.oms.model.entity.orderattachment.OrderAttachment;
import com.zmn.oms.model.entity.product.OrderProduct;
import com.zmn.oms.model.entity.serviceitem.OrderServiceItem;
import com.zmn.oms.model.entity.track.OrderTrackQuery;
import com.zmn.oms.model.entity.visit.OrderVisit;
import com.zmn.oms.model.entity.work.OrderWork;
import com.zmn.oms.model.vo.order.open.AvailableTimeslotsVO;
import com.zmn.oms.model.vo.order.open.OrderInfoVO;
import com.zmn.oms.model.vo.order.open.OrderServiceItemVO;
import com.zmn.oms.model.vo.remark.OrderRemarkDetailVO;
import com.zmn.oms.model.vo.remark.OrderRemarkVO;
import com.zmn.oms.model.vo.track.OrderTrackVO;
import com.zmn.oms.model.vo.work.ZsOrderWorkVO;
import com.zmn.oms.model.vo.work.schedule.OrderScheduleVO;
import com.zmn.oms.services.interfaces.detail.OrderDetailService;
import com.zmn.oms.services.interfaces.master.OrderMasterService;
import com.zmn.oms.services.interfaces.order.OrderExtendService;
import com.zmn.oms.services.interfaces.orderattachment.OrderAttachmentService;
import com.zmn.oms.services.interfaces.product.OrderProductService;
import com.zmn.oms.services.interfaces.visit.OrderVisitService;
import com.zmn.oms.services.interfaces.work.OrderWorkAmountService;
import com.zmn.oms.services.interfaces.work.OrderWorkService;
import com.zmn.oms.third.base.util.ProductIdUtil;
import com.zmn.oms.third.base.util.ThirdOrderUtil;
import com.zmn.oms.third.taobao.TaobaoMapper;
import com.zmn.oms.zmn.business.interfaces.discount.ChannelDiscountService;
import com.zmn.oms.zmn.business.interfaces.docking.ChannelDockingBService;
import com.zmn.oms.zmn.business.interfaces.work.ZsOrderWorkQueryBService;
import com.zmn.oms.zmn.business.interfaces.work.ZsOrderWorkScheduleBService;
import com.zmn.oms.zmn.business.interfaces.work.orderpay.ZsOrderPayBService;
import com.zmn.oms.zmn.normal.business.interfaces.serviceitem.ZsNormalOrderServiceItemBService;
import com.zmn.oms.zmn.normal.business.interfaces.work.ZsNormalWorkBService;
import com.zmn.oms.zmn.normal.business.interfaces.work.masterwork.ZsNormalMasterWorkBService;
import com.zmn.pay.common.constant.PayConsts;
//import com.zmn.plat.common.dto.orderconfig.documentarycontent.DocumentaryContentDIO;
//import com.zmn.plat.common.dto.orderconfig.documentarycontent.DocumentaryContentDRO;
//import com.zmn.plat.dubbo.interfaces.orderconfig.documentarycontent.DocumentaryContentListRemoteService;
import com.zmn.uuc.common.dio.user.UserRegisterByMobileNoCaptchaDIO;
import com.zmn.uuc.common.dio.user.UserTempRegisterDIO;
import com.zmn.uuc.common.dro.user.UserBaseDRO;
import com.zmn.uuc.common.query.user.UserMobilePlatQuery;
import com.zmn.uuc.dubbo.interfaces.user.UserListRemoteService;
import com.zmn.uuc.dubbo.interfaces.user.UserModifyRemoteService;
import com.zmn.uuc.dubbo.interfaces.user.UserRegisterRemoteService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.validation.constraints.NotNull;
import java.util.*;

/**
 * 渠道对接接口实现
 * @author xiewenbing
 * @date 2021/03/24
 */
@Slf4j
@Service
public class ChannelDockingBServiceImpl implements ChannelDockingBService {

    @Autowired
    private OrderDetailService orderDetailService;

    @Autowired
    private OrderWorkService orderWorkService;

    @Autowired
    private OrderVisitService orderVisitService;

    @Autowired
    private OrderRemarkBService orderRemarkBService;

    @Autowired
    private OrderProductService orderProductService;

    @Autowired
    private OrderExtendService orderExtendService;

    @Autowired
    private ZsNormalWorkBService zsNormalWorkBService;

    @Autowired
    private OrderLogBService orderLogBService;

    @Autowired
    private OrderMasterService orderMasterService;

    @Autowired
    private OrderWorkAmountService orderWorkAmountService;

    @Autowired
    private OrderWorkAmountBService orderWorkAmountBService;

    @Autowired
    private ZsOrderPayBService zsOrderPayBService;

    @Autowired
    private OrderDiscountBService orderDiscountBService;

    @Autowired
    private ZsNormalOrderServiceItemBService zsNormalOrderServiceItemBService;

    @Autowired
    private ZsNormalMasterWorkBService zsNormalMasterWorkBService;

    @Autowired
    private DuplicateOrderBService duplicateOrderBService;

    @Autowired
    private ZsOrderWorkScheduleBService zsOrderWorkScheduleBService;

    @Autowired
    private ChannelDiscountService channelDiscountService;

    @Autowired
    private OrderCommentBService orderCommentBService;

    @Autowired
    private OrderTrackBService orderTrackBService;

    @Autowired
    private OrderAttachmentService orderAttachmentService;

    @Autowired
    private ZsOrderWorkQueryBService zsOrderWorkQueryBService;

    @Autowired
    private ServItemBService servItemBService;

    @Resource
    private UserOperationLogClient logClient;

    @Reference(version = com.zmn.base.plat.engine.common.constant.DubboConsts.INTERFACE_VERSION , check = false)
    private ProductForeignListRemoteService productForeignListRemoteService;

//    @Reference(version = com.zmn.base.plat.engine.common.constant.DubboConsts.INTERFACE_VERSION , check = false)
//    private FactoryListRemoteService factoryListRemoteService;

    @Reference(version = com.zmn.base.plat.engine.common.constant.DubboConsts.INTERFACE_VERSION , check = false)
    private AreaListRemoteService areaListRemoteService;

    @Reference(version = com.zmn.base.plat.engine.common.constant.DubboConsts.INTERFACE_VERSION , check = false)
    private ChannelListRemoteService channelListRemoteService;

    @Reference(version = com.zmn.uuc.common.constant.DubboConsts.INTERFACE_VERSION, check = false)
    private UserRegisterRemoteService userRegisterRemoteService;

    @Reference(version = com.zmn.uuc.common.constant.DubboConsts.INTERFACE_VERSION, check = false)
    private UserListRemoteService userListRemoteService;

    @Reference(version = com.zmn.uuc.common.constant.DubboConsts.INTERFACE_VERSION, check = false)
    private UserModifyRemoteService userModifyRemoteService;

//    @Reference(version = com.zmn.base.plat.engine.common.constant.DubboConsts.INTERFACE_VERSION , check = false)
//    protected DocumentaryContentListRemoteService documentaryContentListRemoteService;

    @Reference(version = com.zmn.mos.dubbo.utils.DubboConsts.INTERFACE_VERSION, check = false)
    private ChannelApiOrderRemoteService channelApiOrderRemoteService;

   // @Reference(version = com.zmn.base.engineer.common.constants.DubboConsts.INTERFACE_VERSION, check = false)
   // private BaseInfoListRemoteService baseInfoListRemoteService;

    @Reference(version = com.zmn.base.engineer.common.constants.DubboConsts.INTERFACE_VERSION, check = false)
    private EngineerListRemoteService engineerListRemoteService;

    // 缺省城市id为重庆
    protected final static int DEFAULT_CITY_ID = 500100;

    // 空跑单金额
    private static final int ONLY_RUN_ORDER_AMOUNT = 3000;

    /**
     * 查询订单
     *
     * @param orderId
     * @param channelId
     * @return
     * @throws OmsBaseException
     */
    @Override
    public OrderInfoVO queryOrder(@NotNull(message = "订单id不能为空") Long orderId, Integer channelId) throws OmsBaseException {

        log.info("#ChannelDockingBService#queryOrder......[{}][{}]",orderId,channelId);

        // 校验渠道订单信息
        OrderWork orderWork = this.validateChannelOrder(orderId, channelId);

        // 查询订单详情
        OrderDetail dbOrderDetail = orderDetailService.findOrderDetailByKey(orderWork.getOrderId());

        // 订单详情
        OrderInfoVO orderInfoVO = BeanMapper.map(orderWork, OrderInfoVO.class);
        orderInfoVO.setContactName(StringUtils.defaultIfBlank(dbOrderDetail.getContactName(), dbOrderDetail.getUserName()));
        orderInfoVO.setTelephone(dbOrderDetail.getTelephone());
        orderInfoVO.setCityId(orderWork.getCityId());
        orderInfoVO.setLongitude(dbOrderDetail.getLongitude());
        orderInfoVO.setLatitude(dbOrderDetail.getLatitude());
        orderInfoVO.setServCategId(orderWork.getServCategId());
        orderInfoVO.setThirdOrderId(orderWork.getOuterId());
        orderInfoVO.setServCategName(GlobalConsts.getServCategName(orderWork.getServCategId()));
        orderInfoVO.setStreet(StringUtils.defaultString(dbOrderDetail.getStreet()));
        orderInfoVO.setAddress(String.format("%s%s%s%s%s", dbOrderDetail.getProvinceName(), dbOrderDetail.getCityName(),dbOrderDetail.getCountyName(),
                StringUtils.defaultString(dbOrderDetail.getStreet()), StringUtils.defaultString(dbOrderDetail.getAddress())));

        // 工程师
        if (NumberUtil.isNotNullOrZero(orderWork.getMasterId())) {

            orderInfoVO.setMasterId(orderWork.getMasterId());

            // 隐私小号
            if (Objects.equals(dbOrderDetail.getBindStatus(), OrderConsts.BIND_STATUS_BIND)) {
                orderInfoVO.setBindTelephone(dbOrderDetail.getBindTelephone());
            }

            // 电话
            // todo fubiao
            log.info("queryOrder#getEngineerById start [{}]",orderWork.getMasterId());
            ResponseDTO<ForeignEngineerBasicInfoDRO> basicInfoDROResponseDTO = engineerListRemoteService.getEngineerById(orderWork.getMasterId());
            log.info("queryOrder#getEngineerById end [{}]",JSON.toJSONString(basicInfoDROResponseDTO));
            if (basicInfoDROResponseDTO.isSuccess() && Objects.nonNull(basicInfoDROResponseDTO.getData())) {
                orderInfoVO.setMasterPhone(basicInfoDROResponseDTO.getData().getMobile());
            }
        }

        // 订单状态
        Integer workStatus = orderWork.getStatus();
        Integer resultStatus = orderWork.getResultStatus();
        Integer orderStatus = OrderStatusConsts.getOrderStatus(workStatus, resultStatus);

        orderInfoVO.setStatus(orderStatus);
        orderInfoVO.setStatusName(OrderStatusConsts.getOrderStatusName(orderStatus));

        // 订单取消，取消备注
        if (Objects.equals(OrderStatusConsts.ORDER_STATUS_CANCEL, orderStatus)) {

            // 取消备注
            orderInfoVO.setCancelRemark(queryOrderRemark(orderWork.getOrderId(), orderWork.getWorkId(),
                    OrderConsts.ORDER_REMARK_TYPE_CANCEL));

            // 订单取消时间
            orderInfoVO.setCancelTime(orderWork.getResultTime());
        }

        // 订单完成，服务项和空跑单判断 2021-08-23
        if (Objects.equals(OrderStatusConsts.ORDER_STATUS_COMPLETE, orderStatus)) {

            // 服务项
            List<OrderServiceItem> serviceItemList = zsNormalOrderServiceItemBService.listByOrderId(orderId);
            if (CollectionUtil.isNotNullOrEmpty(serviceItemList)) {
                orderInfoVO.setServiceItems(BeanMapper.mapList(serviceItemList, OrderServiceItemVO.class));
            }

            // 空跑单
            if (Objects.equals(orderWork.getOriginalAmount(),ONLY_RUN_ORDER_AMOUNT)) {
                orderInfoVO.setOnlyRun(GlobalConsts.YES);
            }
        }

        // 查询产品信息
        List<OrderProduct> orderProductList = orderProductService.listOrderProductByOrderId(orderId);
        if (CollectionUtil.isNotNullOrEmpty(orderProductList)) {

            if (NumberUtil.isNullOrZero(orderProductList.get(0).getShowProductId())) {
                orderInfoVO.setProductId(orderProductList.get(0).getProductId());
                orderInfoVO.setProductName(orderProductList.get(0).getProductName());
            } else {
                orderInfoVO.setProductId(orderProductList.get(0).getShowProductId());
                orderInfoVO.setProductName(orderProductList.get(0).getShowProductName());
            }

            orderInfoVO.setProductCount(orderProductList.get(0).getNumber());
        }

        // 扩展信息 和 图片
        StringBuilder imageSrc = new StringBuilder();

        // 读取 oms_order_attachment 的工单照片
        List<OrderAttachment> orderAttachments = orderAttachmentService.listAttachmentByOrderId(orderId);
        if (!org.springframework.util.CollectionUtils.isEmpty(orderAttachments)) {
            for (OrderAttachment orderAttachment : orderAttachments) {
                if (!StringUtil.isNotBlank(orderAttachment.getSrc())) {
                    imageSrc.append(orderAttachment.getSrc()).append(",");
                }
            }
        }

        // 订单扩展信息
        OrderExtend orderExtend = orderExtendService.findOrderExtendByOrderId(orderId);
        if (Objects.nonNull(orderExtend)) {

            orderInfoVO.setOuterData(orderExtend.getOuterData());
            orderInfoVO.setExtOuterData(orderExtend.getExtOuterData());
            orderInfoVO.setExtraData(orderExtend.getExtraData());

            if (!StringUtil.isNotBlank(orderExtend.getImageSrc())) {
                imageSrc.append(orderExtend.getImageSrc());
            }
        }

        orderInfoVO.setProductPictureUrls(imageSrc.toString());

        // 多次上门信息
        List<OrderVisit> orderVisitList = orderVisitService.listByOrderId(orderId);
        for (OrderVisit orderVisit : orderVisitList) {

            if (Objects.equals(orderVisit.getVisitStatus(), OrderVisitStatusConsts.ORDER_VISIT_STATUS_VISIT) ||
                    Objects.equals(orderVisit.getVisitStatus(), OrderVisitStatusConsts.ORDER_VISIT_STATUS_CANCEL)) {
                continue;
            }

            orderInfoVO.setMultipleVisitType(orderVisit.getVisitType());
            orderInfoVO.setMultipleExpectVisitTime(orderVisit.getExpectVisitTime());
            break;
        }

        return orderInfoVO;
    }

    /**
     * 获取预约时间
     *
     * @param availableTimeslotsQuery
     * @return
     */
    @Override
    public List<AvailableTimeslotsVO> queryAvailableTimeslots(AvailableTimeslotsQuery availableTimeslotsQuery) throws OmsBaseException {

        log.info("#ChannelDockingBService#queryAvailableTimeslots......[{}]",availableTimeslotsQuery);

        ResponseDTO<List<ProductBaseDRO>> responseDTO = null;

        // 1、查询产品
        ProductBaseQuery productDIO = new ProductBaseQuery();
        productDIO.setProductId(availableTimeslotsQuery.getProductId());

        try {
            responseDTO = productForeignListRemoteService.listBaseDROByQuery(productDIO);
        } catch (Exception ex) {
            log.error(ex.getMessage());
        }

        if (responseDTO == null || !responseDTO.isSuccess() || CollectionUtil.isNullOrEmpty(responseDTO.getData())) {
            throw new OmsBaseException(StatusConsts.ERROR_DATA, "产品不存在！");
        }

        // 2、获取预约时间
        List<AvailableTimeslotsVO> timeList = Lists.newArrayList();

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());

        for (int i = 0; i < 7; i++) {

            String day = DateUtil.toString(calendar.getTime(), DateUtil.FORMAT_DATE);
            AvailableTimeslotsVO availableTimeslotsVO = new AvailableTimeslotsVO();
            availableTimeslotsVO.setDate(day);
            OrderScheduleVO orderScheduleVO = zsOrderWorkScheduleBService.getCustomerScheduleTimes(day);
            availableTimeslotsVO.setTimeslots(orderScheduleVO.getTimes());
            timeList.add(availableTimeslotsVO);
            calendar.add(Calendar.DAY_OF_YEAR, 1);
        }

        return timeList;
    }

    /**
     * 创建订单
     * @param createOrderDTO
     * @return
     * @throws OmsBaseException
     */
    @Override
    public OrderWork createOrder(CreateOrderDTO createOrderDTO) throws OmsBaseException {

        log.info("#ChannelDockingBService#createOrder......[{}]",createOrderDTO);

        boolean secondCreate = false;

        while(true) {

            if (secondCreate) {
                createOrderDTO.getOrderProductList().get(0).setProductShowType(GlobalConsts.NO);
                createOrderDTO.getOrderProductList().get(0).setProductId(OrderConsts.CHANNEL_DISABLED_PRODUCT_ID);
                ThirdOrderUtil.fillDefaultOrderInfo(createOrderDTO, "；常规保存订单失败，需人工确认");
            }

            try {
                return doCreateOrder(createOrderDTO);

            } catch (Exception e) {

                log.info("[{}]保存订单失败。 ChannelId:[{}], OuterData:[{}]",secondCreate ? "" : "常规",createOrderDTO.getChannelId(), createOrderDTO.getOuterData());
                log.error(e.getMessage(), e);

                if (secondCreate) {
                    throw new OmsBaseException("保存订单失败");
                } else {
                    secondCreate = true;
                }
            }
        }
    }

    /**
     * 取消订单
     *
     * @param cancelOrderDTO
     * @throws OmsBaseException
     */
    @Override
    public void cancelOrder(CancelOrderDTO cancelOrderDTO) throws OmsBaseException {

        log.info("#ChannelDockingBService#cancelOrder......[{}]",cancelOrderDTO);

        Long orderId = cancelOrderDTO.getOrderId();
        Integer channelId = cancelOrderDTO.getChannelId();

        // 校验渠道订单信息
        OrderWork orderWork = this.validateChannelOrder(orderId,channelId);

        // 订单状态为弃单或已取消
        if (Objects.equals(OrderStatusConsts.WORK_RESULT_DISCARD, orderWork.getResultStatus()) ||
                Objects.equals(OrderStatusConsts.WORK_RESULT_FAIL, orderWork.getResultStatus())) {
            throw new OmsBaseException(StatusConsts.ERROR_DATA, "订单已取消，不可重复取消");
        }

        // 订单状态为已完成，或者工程师维修完成
        if (Objects.equals(OrderStatusConsts.WORK_RESULT_SUCCESS, orderWork.getResultStatus()) ||
                orderWork.getCompleteTime() != null) {
            throw new OmsBaseException(StatusConsts.ERROR_DATA, "订单已完成，不可取消");
        }

        ZsCancelDTO zsCancelDTO = BeanMapper.map(cancelOrderDTO, ZsCancelDTO.class);

        // 取消参数
        zsCancelDTO.setOrderId(cancelOrderDTO.getOrderId());
        zsCancelDTO.setWorkId(cancelOrderDTO.getOrderId());
        zsCancelDTO.setContent(cancelOrderDTO.getRemark());

        // 超时未支付取消
        if (!Objects.equals(GlobalConsts.YES, cancelOrderDTO.getPayTimeout())) {
            zsCancelDTO.setPayTimeout(GlobalConsts.NO);
        }

        // 退款取消
        if (!Objects.equals(GlobalConsts.YES, cancelOrderDTO.getRefundCancel())) {
            zsCancelDTO.setRefundCancel(GlobalConsts.NO);
        }

        zsNormalWorkBService.saveCancel(zsCancelDTO);

        this.saveOuterData(orderId, cancelOrderDTO.getOuterData());
    }

    /**
     * 渠道支付
     *
     * @param payOrderDTO
     * @throws Exception
     */
    @Override
    @Transactional
    public void payOrder(@NotNull(message = "参数不能为空")PayOrderDTO payOrderDTO) throws Exception {

        log.info("#ChannelDockingBService#payOrder......[{}]",payOrderDTO);

        // 工单信息
        OrderWork orderWork  = this.validateChannelOrder(payOrderDTO.getOrderId(), payOrderDTO.getChannelId());

        if (Objects.equals(payOrderDTO.getOrderPayType(), OrderConsts.API_ORDER_PAY_TYPE_CHANNEL_PREPAID)) {

            // 渠道预付
            this.saveChannelPrepay(orderWork, payOrderDTO);
        } else {
            String lockKey = String.format("%s", payOrderDTO.getOrderId());
            DistributedLock lock = DistributedLockUtils.build(LockConsts.LOCK_ORDER_AMOUNT + lockKey, LockConsts.LOCK_VALID_TIME);
            try {
                if (lock.tryLock()) {
                    // 渠道二次支付
                    this.saveChannelSecondPay(orderWork, payOrderDTO);
                }
            } catch (Exception e) {
                log.error("渠道第二次支付异常" + e.getMessage(), e);
            }finally {
                lock.unlock();
            }
        }

        // 保存 outerData
        this.saveOuterData(orderWork.getOrderId(), payOrderDTO.getOuterData());

        // 添加操作日志
        if (StringUtils.isNotBlank(payOrderDTO.getOperatorRemark())) {
            this.saveOrderLog(orderWork, OrderLogConsts.ORDER_LOG_TYPE_CHANNEL_REMARK, payOrderDTO.getOperatorRemark());
        }
    }

    /**
     * 保存订单日志
     *
     * @param orderLogDTO
     * @throws OmsBaseException
     */
    @Override
    public void saveOrderLog(@NotNull(message = "参数不能为空")OrderLogDTO orderLogDTO) throws OmsBaseException {

        log.info("#ChannelDockingBService#saveOrderLog......[{}]",orderLogDTO);

        // 工单信息
        OrderWork orderWork  = this.validateChannelOrder(orderLogDTO.getOrderId(), orderLogDTO.getChannelId());
        StringBuilder sbLogContent = new StringBuilder();
        sbLogContent.append(Optional.ofNullable(orderLogDTO.getOperatorRemark()).orElse(""))
                .append(Optional.ofNullable(orderLogDTO.getOperatorLogRemark()).orElse(""));
        this.saveOrderLog(orderWork,OrderLogConsts.ORDER_LOG_TYPE_CHANNEL_REMARK, sbLogContent.toString());
    }

    /**
     * 保存订单评价
     *
     * @param commentDTO
     * @throws OmsBaseException
     */
    @Override
    public void saveOrderComment(@NotNull(message = "参数不能为空")CommentDTO commentDTO) throws OmsBaseException {

        log.info("#ChannelDockingBService#saveOrderComment......[{}]",commentDTO);

        // 工单信息
        OrderWork orderWork  = this.validateChannelOrder(commentDTO.getOrderId(), commentDTO.getChannelId());

        // 保存评价数据
        OrderCommentDTO orderCommentDTO = BeanMapper.map(commentDTO, OrderCommentDTO.class);
        orderCommentDTO.setOrderId(orderWork.getOrderId());
        orderCommentDTO.setWorkId(orderWork.getWorkId());
        orderCommentDTO.setType(OrderConsts.COMMENT_TYPE_THIRD);
        orderCommentDTO.setOperatorType(com.zmn.consts.GlobalConsts.OPERATE_USER_TYPE_USER);
        orderCommentDTO.setOperatorId(0l);
        orderCommentDTO.setOperator("系统");
        orderCommentBService.saveThirdComment(orderCommentDTO);

        /** 同步代码  2021-05-17
        // 更新渠道投诉等级
        if (Objects.nonNull(commentDTO.getScore())) {
            this.updateChannelComplaintLevel(orderWork, commentDTO.getScore());
        }
         */
    }

    /**
     * 修改订单信息，包括预约时间，用户地址和电话，渠道订单id，渠道扩展信息，渠道预付状态，可弃单状态等
     *
     * @param updateOrderDTO
     * @throws OmsBaseException
     */
    @Override
    public void updateOrder(@NotNull(message = "参数不能为空")UpdateOrderDTO updateOrderDTO) throws OmsBaseException {

        log.info("#ChannelDockingBService#updateOrder......[{}]",updateOrderDTO);

        // 工单信息
        OrderWork orderWork  = this.validateChannelOrder(updateOrderDTO.getOrderId(), updateOrderDTO.getChannelId());

        // 修改渠道订单id
        if (StringUtils.isNotBlank(updateOrderDTO.getOuterId())) {
            OrderWork updateOrderWork = new OrderWork();
            updateOrderWork.setOrderId(orderWork.getOrderId());
            updateOrderWork.setWorkId(orderWork.getWorkId());
            updateOrderWork.setOuterId(updateOrderDTO.getOuterId());
            orderWorkService.updateOrderWorkByKey(updateOrderWork);
        }

        // 修改预约时间
        if (Objects.nonNull(updateOrderDTO.getDutyTime())) {
            OrderWork updateOrderWork = new OrderWork();
            updateOrderWork.setOrderId(orderWork.getOrderId());
            updateOrderWork.setWorkId(orderWork.getWorkId());
            updateOrderWork.setDutyTime(updateOrderDTO.getDutyTime());
            orderWorkService.updateOrderWorkDutyTimeByKey(updateOrderWork);
        }

        // 修改客户联系电话 & 修改客户地址
        boolean phoneIsChanged = StringUtils.isNotBlank(updateOrderDTO.getPhone());
        boolean addressIsChanged = StringUtils.isNotBlank(updateOrderDTO.getAddress());

        if (phoneIsChanged || addressIsChanged) {
            // 工单详情
            OrderDetail updateOrderDetail = new OrderDetail();
            updateOrderDetail.setDetailId(updateOrderDTO.getOrderId());

            // 修改用户的电话信息
            if (phoneIsChanged) {
                this.changeUserMobile(orderWork,updateOrderDTO.getPhone());
                updateOrderDetail.setTelephone(updateOrderDTO.getPhone());
            }

            // 修改客户地址
            if (addressIsChanged) {
                updateOrderDetail.setAddress(updateOrderDTO.getAddress());
            }

            orderDetailService.updateOrderDetailByKey(updateOrderDetail);
        }

        // 修改渠道预付状态和可弃单状态
        if (Objects.nonNull(updateOrderDTO.getDisableDiscard()) || Objects.nonNull(updateOrderDTO.getChannelPrepayStatus())) {
            OrderWork updateOrderWork = new OrderWork();
            updateOrderWork.setOrderId(orderWork.getOrderId());
            updateOrderWork.setWorkId(orderWork.getWorkId());
            updateOrderWork.setChannelPrepayStatus(updateOrderDTO.getChannelPrepayStatus());
            updateOrderWork.setDisableDiscard(updateOrderDTO.getDisableDiscard());
            orderWorkService.updateOrderWorkByKey(updateOrderWork);
        }

        // 更新外部订单信息
        if (StringUtils.isNotBlank(updateOrderDTO.getOuterData())) {
            this.saveOuterData(orderWork.getOrderId(), updateOrderDTO.getOuterData());
        }

        // 日志
        if (StringUtil.isNotBlank(updateOrderDTO.getOperatorRemark()) || StringUtils.isNotBlank(updateOrderDTO.getOperatorLogRemark())) {
            StringBuilder sbLogContent = new StringBuilder();
            sbLogContent.append(Optional.ofNullable(updateOrderDTO.getOperatorRemark()).orElse(""))
                    .append(Optional.ofNullable(updateOrderDTO.getOperatorLogRemark()).orElse(""));
            this.saveOrderLog(orderWork,OrderLogConsts.ORDER_LOG_TYPE_CHANNEL_REMARK, sbLogContent.toString());
        }
    }

    /**
     * 发起订单自动跟单
     * @param orderAutoTrackDTO
     * @throws OmsBaseException
     */
    @Override
    public void updateOrderAutoTrack(@NotNull(message = "参数不能为空")OrderAutoTrackDTO orderAutoTrackDTO) throws OmsBaseException {

        // 工单信息
        OrderWork orderWork  = this.validateChannelOrder(orderAutoTrackDTO.getOrderId(), orderAutoTrackDTO.getChannelId());

        //查询是否存在用户签收跟单 && 跟单未完成
        OrderTrackQuery query = new OrderTrackQuery();
        query.setOrderId(orderAutoTrackDTO.getOrderId());
        query.setWorkId(orderAutoTrackDTO.getWorkId());
        query.setMapId(orderAutoTrackDTO.getMapId());
        query.setComplete(orderAutoTrackDTO.getComplete());
        Integer orderTrackCount = orderTrackBService.countByQuery(query);
        log.info("#ChannelDockingBServiceImpl#orderTrackCount 查询跟单是否完成：【{}】", JSON.toJSONString(orderTrackCount));
        // 有进行中的跟单则不创建跟单
        if (orderTrackCount != null && orderTrackCount > 0) {
            throw new OmsBaseException("有进行中的跟单");
        }

        //查询指定的跟单信息
        /*List<OrderTrackVO> trackTypeList = Lists.newArrayList();
        DocumentaryContentDIO documentaryContentDIO = new DocumentaryContentDIO();
        documentaryContentDIO.setBizType(orderWork.getBizType());
        documentaryContentDIO.setStatus(com.zmn.common.constant.GlobalConsts.YES);
        documentaryContentDIO.setId(orderAutoTrackDTO.getMapId());
        log.info("#ChannelDockingBServiceImpl#track 查询跟单项目入参：【{}】", JSON.toJSONString(documentaryContentDIO));
        ResponseDTO<List<DocumentaryContentDRO>> responseDTO = documentaryContentListRemoteService.listByQuery(documentaryContentDIO);
        log.info("#ChannelDockingBServiceImpl#track 查询跟单项目出参：【{}】", JSON.toJSONString(responseDTO));

        if (!responseDTO.isSuccess() || CollectionUtils.isEmpty(responseDTO.getData())) {
           throw new OmsBaseException("查询跟单项失败或为空");
        }

        responseDTO.getData().forEach(e -> {
            // 默认跟单等级为一级
            OrderTrackVO orderTrackVO = OrderTrackVO.builder().mapId(e.getId()).mapName(e.getContent()).level(OrderConsts.ORDER_TRACT_OTHER_TYPE_LEVEL).build();
            trackTypeList.add(orderTrackVO);
        });

        // 保存跟单信息
        OrderTrackDTO orderTrackDTO = new OrderTrackDTO();
        orderTrackDTO.setComplete(com.zmn.common.constant.GlobalConsts.NO);
        orderTrackDTO.setOrderId(orderWork.getOrderId());
        orderTrackDTO.setWorkId(orderWork.getWorkId());
        orderTrackDTO.setOperator("系统");
        orderTrackDTO.setOperatorId((long) orderWork.getChannelId());
        orderTrackDTO.setOperatorType(com.zmn.common.constant.GlobalConsts.OPERATE_USER_TYPE_CHANNEL);

        List<OrderTrackDetailDTO> detailDTOList = new ArrayList<>(trackTypeList.size());
        orderTrackDTO.setDetailDTOList(detailDTOList);

        trackTypeList.forEach(workTrackDTO -> {

            // 添加到跟单列表
            OrderTrackDetailDTO orderTrackDetailDTO = new OrderTrackDetailDTO();
            orderTrackDetailDTO.setMapId(workTrackDTO.getMapId());
            orderTrackDetailDTO.setMapName(workTrackDTO.getMapName());
            orderTrackDetailDTO.setRemark(workTrackDTO.getRemark());
            orderTrackDetailDTO.setLevel(workTrackDTO.getLevel());
            detailDTOList.add(orderTrackDetailDTO);
        });

        // 保存
        orderTrackBService.updateTrack(orderTrackDTO);*/
    }

    /**
     * 创建订单
     * @param createOrderDTO
     * @return
     * @throws OmsBaseException
     */
    private OrderWork doCreateOrder(CreateOrderDTO createOrderDTO) throws OmsBaseException {

        // 重复单检测
        this.checkDuplicateOrderClue(createOrderDTO);

        // 城市id
        this.checkAndSetCityId(createOrderDTO);

        ChannelApiOrderAddDIO addDIO = this.buildChannelApiOrderAddDIO(createOrderDTO);

        log.info("渠道接口下单入参[{}]", JSON.toJSONString(addDIO));
        ResponseDTO<OrderAddDRO> responseDTO = channelApiOrderRemoteService.addOrder(addDIO);

        log.info("渠道接口下单出参[{}]", JSON.toJSONString(responseDTO));
        if (!responseDTO.isSuccess()) {
            throw new OmsBaseException(responseDTO.getMessage());
        }

        // 录单埋点  2021-05-17 同步代码去掉
        // this.addOrderEventLog(orderBO, createOrderDTO);

        Long orderId = responseDTO.getData().getOrderId();
        return orderWorkService.findOrderWorkByKey(orderId,orderId);
    }

    /**
     * 订单线索重复检测
     * @param createOrderDTO
     * @throws OmsBaseException
     */
    private void checkDuplicateOrderClue(CreateOrderDTO createOrderDTO) throws OmsBaseException{

        // 参数判断
        if (Objects.isNull(createOrderDTO)) {
            throw new OmsBaseException("订单创建数据不能为null");
        }

        // 渠道id 和 渠道订单判断
        if (NumberUtil.isNullOrZero(createOrderDTO.getChannelId()) || StringUtil.isBlank(createOrderDTO.getOuterId())) {
            return;
        }

        // 线索重复检测
        ZsOrderWorkVO zsOrderWorkVO = zsOrderWorkQueryBService.findOrderWorkByOuterId(createOrderDTO.getOuterId(),
                createOrderDTO.getChannelId());
        if (Objects.nonNull(zsOrderWorkVO)) {

            throw new OmsBaseException("重复的订单线索数据");
        }
    }

    /**
     * 检测并设置城市id
     * @param createOrderDTO
     */
    private void checkAndSetCityId(CreateOrderDTO createOrderDTO) {

        if (Objects.isNull(createOrderDTO)) {
            return;
        }

        // 已经设置不做处理
        if (NumberUtil.isNotNullOrZero(createOrderDTO.getCityId())) {
            return;
        }

        Integer cityId = 0;

        // 1.存在经纬度时，优先使用经纬度获取
        if (Objects.nonNull(createOrderDTO.getLongitude()) && Objects.nonNull(createOrderDTO.getLatitude())) {
            cityId = Optional.ofNullable(areaListRemoteService.getAreaByLatAndLng(createOrderDTO.getLongitude(), createOrderDTO.getLatitude()))
                    .map(areaResponse -> areaResponse.isSuccess() ? areaResponse.getData() : null)
                    .map(areaDRO -> areaDRO.getParentId())
                    .orElse(null);
        }


        if (NumberUtil.isNullOrZero(cityId)) {
            // 2.使用逆地址解析获取
            String addressInfo = String.format("%s%s",
                    StringUtil.isBlank(createOrderDTO.getStreet()) ? "" : createOrderDTO.getStreet().trim(),
                    StringUtil.isBlank(createOrderDTO.getAddress()) ? "" : createOrderDTO.getAddress().trim()
            );

            if (StringUtil.isNotBlank(addressInfo)) {
                cityId = Optional.ofNullable(areaListRemoteService.getAreaByAddress(addressInfo))
                        .map(areaResponse -> areaResponse.isSuccess() ? areaResponse.getData() : null)
                        .map(areaDRO -> areaDRO.getParentId())
                        .orElse(null);
            }
        }

        createOrderDTO.setCityId(NumberUtil.isNullOrZero(cityId) ? DEFAULT_CITY_ID : cityId);
    }

    // region 封装统一录单对象
    /**
     * 录入厂商单
     * @param createOrderDTO
     * @return
     * @throws OmsBaseException
     */
    private ChannelApiOrderAddDIO buildChannelApiOrderAddDIO(CreateOrderDTO createOrderDTO) throws OmsBaseException {

        ChannelApiOrderAddDIO orderAddDIO = BeanMapper.map(createOrderDTO, ChannelApiOrderAddDIO.class);

        // 校验并设置厂商信息
        this.setFactoryOfOrderAddDIO(createOrderDTO,orderAddDIO);

        // 用户信息
        this.setUserOfOrderAddDIO(createOrderDTO,orderAddDIO);

        // 订单基础信息
        this.setBaseOfOrderAddDIO(createOrderDTO,orderAddDIO);

        // 产品信息
        this.setProductOfOrderAddDIO(createOrderDTO, orderAddDIO);

        // 渠道扩展信息
        this.setChannelExtraOfOrderAddDIO(createOrderDTO, orderAddDIO);

        // 预约时间
        this.setDutyTimeOfOrderAddDIO(createOrderDTO,orderAddDIO);

        // 操作人为渠道
        this.setOperatorOfOrderAddDIO(createOrderDTO,orderAddDIO);

        return orderAddDIO;
    }

    /**
     * 设置厂商信息
     * @param createOrderDTO
     * @param orderAddDIO
     * @throws OmsBaseException
     */
    private void setFactoryOfOrderAddDIO(CreateOrderDTO createOrderDTO, ChannelApiOrderAddDIO orderAddDIO) throws OmsBaseException{

        // 普通单跳过
        if (!Objects.equals(GlobalConsts.YES, createOrderDTO.getFactory())) {
            return;
        }

        // 校验厂商信息
        throw new OmsBaseException("厂商服务已下线");
        /*try {
            ResponseDTO<FactoryBaseDRO> factoryResponseDTO = factoryListRemoteService
                    .getFactoryByChannelId(createOrderDTO.getChannelId());

            FactoryBaseDRO factoryBaseDRO = Optional.ofNullable(factoryResponseDTO.getData())
                    .orElseThrow(() -> new OmsBaseException(StatusConsts.ERROR_DATA, "渠道ID有误，未找到对应厂商！"));
            orderAddDIO.setFactoryId(factoryBaseDRO.getFcId());
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            if (e instanceof OmsBaseException) {
                throw (OmsBaseException)e;
            }
            else {
                throw new OmsBaseException(StatusConsts.ERROR_DATA, "查找厂商信息失败！");
            }
        }*/
    }

    /**
     * 设置用户信息
     * @param createOrderDTO
     * @param orderAddDIO
     */
    private void setUserOfOrderAddDIO(CreateOrderDTO createOrderDTO, ChannelApiOrderAddDIO orderAddDIO) {

        UserDIO userDIO = BeanMapper.map(createOrderDTO, UserDIO.class);
        orderAddDIO.setUserDIO(userDIO);

        userDIO.setUserName(
                StringUtils.isNotBlank(userDIO.getContactName()) ? userDIO.getContactName() : "未知"
        );
    }

    /**
     * 设置基础信息
     * @param createOrderDTO
     * @param orderAddDIO
     */
    private void setBaseOfOrderAddDIO(CreateOrderDTO createOrderDTO, ChannelApiOrderAddDIO orderAddDIO) {

        OrderBaseInfo orderBaseInfo = BeanMapper.map(createOrderDTO, OrderBaseInfo.class);
        orderAddDIO.setOrderBaseInfo(orderBaseInfo);

        // 渠道id
        orderBaseInfo.setChannelId(createOrderDTO.getChannelId());

        // 下单方式 - 接口录入
        orderBaseInfo.setReceiverManner(OrderConsts.RECEIVE_MANNER_API);

        // 录入方式 - 默认API
        orderBaseInfo.setInputType(Optional.ofNullable(orderBaseInfo.getInputType()).orElse(OrderConsts.ORDER_INPUT_TYPE_API));

        // 判断订单类型
        if (Objects.equals(GlobalConsts.YES, createOrderDTO.getFactory())) {        // 厂商单

            // 订单类型
            orderBaseInfo.setType(OrderConsts.ORDER_TYPE_NEW);

            // 下单入口 - 定制API
            orderBaseInfo.setReceiveEntranceId(GateTypeConsts.GATE_API_CUSTOM_MADE);

            // 默认平台
            orderBaseInfo.setPlat(Optional.ofNullable(orderBaseInfo.getPlat()).orElse(GlobalConsts.PLAT_MARK_YEYX));

            // 判断是否保内
            orderBaseInfo.setBizType(Optional.ofNullable(orderBaseInfo.getBizType()).orElse(com.zmn.consts.GlobalConsts.BIZ_TYPE_F));

        } else {        // 普通单

            // 订单类型
            orderBaseInfo.setType(Objects.nonNull(createOrderDTO.getOriginalId()) ? OrderConsts.ORDER_TYPE_REWORK : OrderConsts.ORDER_TYPE_NEW);

            // 下单入口
            orderBaseInfo.setReceiveEntranceId(
                    (createOrderDTO.getProxyFromType() == null
                            || Objects.equals(1, createOrderDTO.getProxyFromType())) // 渠道来源 1=API
                            ? GateTypeConsts.GATE_API_CUSTOM_MADE
                            : Objects.equals(2, createOrderDTO.getProxyFromType())   // 渠道来源 2=H5
                            ? GateTypeConsts.GATE_WECHAT_H5_OLD
                            : createOrderDTO.getProxyFromType()
            );

            // 默认平台
            orderBaseInfo.setPlat(Optional.ofNullable(orderBaseInfo.getPlat()).orElse(GlobalConsts.PLAT_MARK_ZMN));

            // 默认业务类型为C端订单
            orderBaseInfo.setBizType(Optional.ofNullable(orderBaseInfo.getBizType()).orElse(com.zmn.consts.GlobalConsts.BIZ_TYPE_C));
        }

    }

    /**
     * 设置产品信息
     * @param createOrderDTO
     * @param orderAddDIO
     */
    private void setProductOfOrderAddDIO(CreateOrderDTO createOrderDTO, ChannelApiOrderAddDIO orderAddDIO) throws OmsBaseException {

        OrderProductDIO orderProductDIO = BeanMapper.map(createOrderDTO.getOrderProductList().get(0), OrderProductDIO.class);
        if (NumberUtil.isNullOrZero(orderProductDIO.getNumber())) {
            orderProductDIO.setNumber(1);
        }

        orderAddDIO.setServCategId(null);

        // 通过产品查询服务分类
        try {
            Integer productId = orderProductDIO.getShowProductId();
            if (NumberUtil.isNullOrZero(productId)) {
                productId = orderProductDIO.getProductId();
            }

            // 修正已失效产品ID lhl-2021.01.08
            productId = ProductIdUtil.getNewProductId(productId);
            if (!NumberUtil.isNullOrZero(productId)) {

                ProductBaseQuery productDIO = new ProductBaseQuery();
                productDIO.setProductId(productId);
                ResponseDTO<List<ProductBaseDRO>> productDROResp = productForeignListRemoteService.listBaseDROByQuery(productDIO);
                Optional.ofNullable(productDROResp.getData()).map(list -> list.get(0)).ifPresent(productBaseDRO -> {

                    orderAddDIO.setServCategId(productBaseDRO.getServCategId());

                    // 修正是否是前台产品ID
                    if (Objects.equals(GlobalConsts.YES, productBaseDRO.getShowType())) {
                        orderProductDIO.setShowProductId(productBaseDRO.getProductId());
                        orderProductDIO.setProductId(0);
                    } else {
                        orderProductDIO.setProductId(productBaseDRO.getProductId());
                    }
                });
            }

            if (Objects.isNull(orderAddDIO.getServCategId())) {
                orderProductDIO.setProductId(OrderConsts.CHANNEL_DISABLED_PRODUCT_ID);
                orderAddDIO.setServCategId(GlobalConsts.SERV_CATEG_REPAIR);
            }
        } catch (Exception e) {
            throw new OmsBaseException("产品不存在", e);
        }

        orderAddDIO.setOrderProductList(Lists.newArrayList(orderProductDIO));
    }

    /**
     * 设置渠道扩展信息
     * @param createOrderDTO
     * @param orderAddDIO
     */
    private void setChannelExtraOfOrderAddDIO(CreateOrderDTO createOrderDTO, ChannelApiOrderAddDIO orderAddDIO) {

        // 渠道扩展信息
        ChannelApiExtraData extraData = BeanMapper.map(createOrderDTO, ChannelApiExtraData.class);
        orderAddDIO.setChannelApiExtraData(extraData);

        // 厂商单不处理渠道预付
        if (Objects.equals(GlobalConsts.YES, createOrderDTO.getFactory())) {
            return;
        }

        StringJoiner logRemarkBuilder = new StringJoiner("；");

        // 渠道预付状态、是否允许禁止弃单
        Integer channelPrepayStatus = Optional.ofNullable(extraData.getChannelPrepayStatus())
                .orElse(PayConsts.PAY_STATUS_NONE);

        Integer disableDiscard = Optional.ofNullable(extraData.getDisableDiscard())
                .orElseGet(() -> {
                    boolean hasChannelPrepayAmount = NumberUtil.isNotNullOrZero(extraData.getChannelPrepayAmount());
                    boolean isPaied = Objects.equals(channelPrepayStatus, PayConsts.PAY_STATUS_DONE);
                    return (hasChannelPrepayAmount && isPaied) ? GlobalConsts.NO : GlobalConsts.YES;
                });

        extraData.setChannelPrepayStatus(channelPrepayStatus);
        extraData.setDisableDiscard(disableDiscard);

       // 处理渠道优惠，xiewenbing 2021/09/30
        List<OrderDiscountDTO> discountList=createOrderDTO.getOrderDiscountList();
        Integer orderDiscountAmount = 0;
        if (CollectionUtils.isNotEmpty(discountList)) {
            orderDiscountAmount = discountList.stream()
                    .filter(item -> NumberUtil.isNotNullOrZero(item.getAmount()))
                    .mapToInt(item -> item.getAmount())
                    .sum();
        }

        // 采用新的保存方式  2020-06-23 by lhl
        // Integer orderDiscountAmount = channelDiscountService.getOrderDiscountAmount(createOrderDTO);
        if (NumberUtil.isNotNullOrZero(orderDiscountAmount)) {
            extraData.setChannelDiscountAmount(orderDiscountAmount);
            logRemarkBuilder.add(String.format("渠道优惠：%s元", MoneyUtil.parseToYuanStr(orderDiscountAmount)));
        }

        Integer channelId = createOrderDTO.getChannelId();
        Integer servCategId = orderAddDIO.getServCategId();
        OrderProductDIO orderProductDIO = orderAddDIO.getOrderProductList().get(0);

        // 设置默认服务项和渠道优惠，号码百事通APP
        if (Objects.equals(channelId, OrderConsts.CHANNEL_ID_HAOBAI_APP) && Objects.equals(servCategId, GlobalConsts.SERV_CATEG_CLEAN)) {
            try {
                // 设置默认服务项
                GetServiceItemDTO getServiceItemDTO = GetServiceItemDTO.builder()
                        .channelId(channelId)
                        .productId(
                                NumberUtil.isNullOrZero(orderProductDIO.getShowProductId())
                                        ? orderProductDIO.getShowProductId()
                                        : orderProductDIO.getProductId()
                        )
                        .productNumber(orderProductDIO.getNumber())
                        .cityId(createOrderDTO.getCityId())
                        .bizType(com.zmn.consts.GlobalConsts.BIZ_TYPE_C)
                        .build();

                log.debug("为号百app设置默认服务项==[{}]", getServiceItemDTO);
                List<OrderServiceItem> orderServiceItems = this.listDefaultServiceItem(getServiceItemDTO);

                // 计算优惠
                if (CollectionUtil.isNotNullOrEmpty(orderServiceItems)) {
                    log.debug("服务项和价格不为空开始计算优惠: GetServiceItemDTO=[{}]",
                            JSON.toJSONString(getServiceItemDTO));

                    int originalAmount = orderServiceItems.stream().mapToInt(e -> e.getTotalPrice()).sum();
                    int totalAmount = Optional.ofNullable(createOrderDTO.getTotalAmount()).orElse(-1);

                    // 如果是要客订单，且没有设置优惠，塞“特殊优惠-全免-总公司承担”
                    if (Objects.equals(GlobalConsts.YES, createOrderDTO.getVvip())) {
                        extraData.setVvip(GlobalConsts.YES);
                        extraData.setUnusualDiscount(GlobalConsts.YES);

                        logRemarkBuilder.add("特殊优惠-全免-总公司承担");
                    }

                    // 存在订单金额（totalAmount != -1）且原价大于订单金额，设置渠道优惠
                    else if (totalAmount >= 0 &&originalAmount > totalAmount) {
                        int discountAmount = MathUtil.sub(originalAmount, totalAmount);
                        extraData.setChannelDiscountAmount(discountAmount);
                        logRemarkBuilder.add(String.format("渠道优惠：%s元，按优惠后金额计算得出",
                                MoneyUtil.parseToYuanStr(discountAmount)
                        ));
                    }
                }
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }
        }

        // 总价为0时，并且已支付，设置优惠立减
        if (Objects.equals(servCategId, GlobalConsts.SERV_CATEG_CLEAN)
                && Objects.equals(createOrderDTO.getTotalAmount(), 0)
                && Objects.equals(createOrderDTO.getChannelPrepayStatus(), PayConsts.PAY_STATUS_DONE)
                && Objects.equals(createOrderDTO.getChannelPrepayAmount(), 0)
                && !NumberUtil.isNullOrZero(createOrderDTO.getOriginalAmount())) {

            // 可以处理订单
            extraData.setDisableDiscard(GlobalConsts.NO);
        }

        if (logRemarkBuilder.length() > 0) {
            orderAddDIO.setOperatorRemark(logRemarkBuilder.toString());
        }
    }

    /**
     * 设置预约时间
     * @param createOrderDTO
     * @param orderAddDIO
     */
    private void setDutyTimeOfOrderAddDIO(CreateOrderDTO createOrderDTO, ChannelApiOrderAddDIO orderAddDIO) {

        if (Objects.equals(GlobalConsts.YES, createOrderDTO.getFactory())) {
            return;
        }

        OrderProductDIO orderProductDIO = orderAddDIO.getOrderProductList().get(0);

        Date dutyTime = createOrderDTO.getDutyTime();
        if (Objects.nonNull(dutyTime) && ((dutyTime.getTime() - (System.currentTimeMillis() + 5*60*1000)) > 0)) {
            // 有预约时间，且不在5分钟之内，为有效预约时间 2021.08.24 by lhl
            orderProductDIO.setDutyTime(dutyTime);
            return;
        }

        // 设置默认预约时间处理 2020-05-19 by lhl
        do {
            // 天猫订单不设置默认预约时间（勤鸽店，B端，勤鸽管道疏通）
            if (TaobaoMapper.isTmallChannel(createOrderDTO.getChannelId())) {
                break;
            }

            // 录单平台是言而有信的，不设置默认预约时间
            if (Objects.equals(GlobalConsts.PLAT_MARK_YEYX, orderAddDIO.getOrderBaseInfo().getPlat())) {
                break;
            }

            orderProductDIO.setDutyTime(ThirdOrderUtil.getDefaultDutyTime());
        } while (false);
    }

    /**
     * 设置操作者相关信息
     * @param createOrderDTO
     * @param orderAddDIO
     */
    private void setOperatorOfOrderAddDIO(CreateOrderDTO createOrderDTO, ChannelApiOrderAddDIO orderAddDIO) {

        StringJoiner logRemarkBuilder = new StringJoiner("；");

        if (StringUtil.isNotBlank(createOrderDTO.getOperatorLogRemark())) {
            logRemarkBuilder.add(createOrderDTO.getOperatorLogRemark());
        }

        if (StringUtil.isNotBlank(createOrderDTO.getRemark())) {
            logRemarkBuilder.add(createOrderDTO.getRemark());
        }

        // 日志记录经纬度信息
        if (createOrderDTO.getLongitude() != null && createOrderDTO.getLatitude() != null) {
            logRemarkBuilder.add(
                    String.format("经纬度：%s,%s", createOrderDTO.getLongitude(), createOrderDTO.getLatitude())
            );
        }

        if (StringUtil.isNotBlank(orderAddDIO.getRemark())){
            logRemarkBuilder.add(orderAddDIO.getRemark());
        }

        // 操作人为渠道
        orderAddDIO.setOperatorType(Optional.ofNullable(createOrderDTO.getOperatorType()).orElse(GlobalConsts.OPERATE_USER_TYPE_CHANNEL));
        orderAddDIO.setOperatorId(NumberUtil.isNotNullOrZero(createOrderDTO.getOperatorId()) ?
                createOrderDTO.getOperatorId() : (long) createOrderDTO.getChannelId());
        orderAddDIO.setOperator(StringUtil.isNotBlank(createOrderDTO.getOperator()) ? createOrderDTO.getOperator() : "系统");

        if (logRemarkBuilder.length() > 0) {
            orderAddDIO.setOperatorRemark(logRemarkBuilder.toString());
        }
    }
    //endregion

    /**
     * 获取默认服务项
     * @param getServiceItemDTO
     * @return
     */
    private List<OrderServiceItem> listDefaultServiceItem(GetServiceItemDTO getServiceItemDTO) {

        CheckQuotationTypeOrderDTO build = CheckQuotationTypeOrderDTO
                .builder()
                .channelId(getServiceItemDTO.getChannelId())
                .cityId(getServiceItemDTO.getCityId())
                .productId(getServiceItemDTO.getProductId())
                .bizType(getServiceItemDTO.getBizType())
                .build();
        Integer servItemType = servItemBService.getServItemType(build);

        // 获取默认服务项
        ServiceItemQueryDTO serviceItemQueryDTO = ServiceItemQueryDTO
                .builder()
                .servItemType(servItemType)
                .channelId(getServiceItemDTO.getChannelId())
                .cityId(getServiceItemDTO.getCityId())
                .productId(getServiceItemDTO.getProductId())
                .bizType(getServiceItemDTO.getBizType())
                .general(GlobalConsts.YES)
                .build();
        ResponseDTO<ServiceItemResultDTO> responseDTO = servItemBService.getServiceItem(serviceItemQueryDTO);
        log.info("获取默认服务项入参[{}]，出参[{}]", JSON.toJSONString(serviceItemQueryDTO), JSON.toJSONString(responseDTO));

        List<OrderServiceItem> defaultServiceItemLists = Lists.newArrayList();

        // 服务项数据为空
        if (!responseDTO.isSuccess() || Objects.isNull(responseDTO.getData())) {
            log.info(responseDTO.getMessage());
            return defaultServiceItemLists;
        }

        ServiceItemResultDTO defaultItem = responseDTO.getData();
        int productNumer = Optional.ofNullable(getServiceItemDTO.getProductNumber()).orElse(1);
        for (int i = 0; i < productNumer; i++) {
            OrderServiceItem orderServiceItem = new OrderServiceItem();
            orderServiceItem.setProductId(getServiceItemDTO.getProductId());
            orderServiceItem.setItemPrice(defaultItem.getPrice());
            orderServiceItem.setNumber(1);
            orderServiceItem.setTotalPrice(defaultItem.getPrice());
            orderServiceItem.setServItemId(defaultItem.getItemId());
            orderServiceItem.setServItemName(defaultItem.getItemName());
            orderServiceItem.setServItemGroupId(Optional.ofNullable(defaultItem.getItemCategId()).orElse(0));
            orderServiceItem.setServItemGroupName(defaultItem.getItemCategName());
            defaultServiceItemLists.add(orderServiceItem);
        }

        log.info("返回默认服务项列表[{}]", defaultServiceItemLists);
        return defaultServiceItemLists;
    }

    /**
     * 订单预付
     *
     * @param orderWork
     * @param payOrderDTO
     * @throws Exception
     */
    private void saveChannelPrepay(OrderWork orderWork, PayOrderDTO payOrderDTO) throws Exception {

        // 改工单的渠道预付和预付状态
        OrderWork updateAmount = new OrderWork();
        updateAmount.setOrderId(orderWork.getOrderId());
        updateAmount.setWorkId(orderWork.getWorkId());
        updateAmount.setChannelPrepayStatus(PayConsts.PAY_STATUS_DONE);
        updateAmount.setChannelPrepayAmount(payOrderDTO.getPayAmount());
        updateAmount.setDisableDiscard(GlobalConsts.NO);
        orderWorkAmountService.updatePayStatusChannelPrepay(updateAmount);

        // 更新到优惠信息 Xiewenbing 2020.04.29
        if (NumberUtil.isNotNullOrZero(payOrderDTO.getDiscountAmount())) {
            AddDiscountDTO addDiscountDTO = new AddDiscountDTO();
            addDiscountDTO.setOrderId(orderWork.getOrderId());
            addDiscountDTO.setWorkId(orderWork.getWorkId());
            addDiscountDTO.setAmount(payOrderDTO.getDiscountAmount());
            addDiscountDTO.setDiscountUserName("系统");
            orderDiscountBService.channelDiscount(addDiscountDTO);
        }

        if (NumberUtil.isNullOrZero(orderWork.getOriginalAmount())) {
            return;
        }

        ValidateWorkAmountDTO validateWorkAmountDTO = new ValidateWorkAmountDTO();
        validateWorkAmountDTO.setOrderId(orderWork.getOrderId());
        validateWorkAmountDTO.setWorkId(orderWork.getWorkId());
        validateWorkAmountDTO.setOriginalAmount(orderWork.getOriginalAmount());

        // 原价验证
        if (orderWorkAmountBService.validateWorkAmount(validateWorkAmountDTO)) {

            // 更新应收、工程师收款金额
            ZsUpdateChannelPrepayAmountDTO channelPrepayAmountDTO = new ZsUpdateChannelPrepayAmountDTO();
            channelPrepayAmountDTO.setOperatorRemark(payOrderDTO.getOperatorRemark());
            channelPrepayAmountDTO.setOperatorLogRemark("渠道支付：" + MoneyUtil.parseToYuan(payOrderDTO.getPayAmount()));
            channelPrepayAmountDTO.setOperatorType(GlobalConsts.OPERATE_USER_TYPE_CHANNEL);
            channelPrepayAmountDTO.setOperatorId((long) GlobalConsts.OPERATE_USER_TYPE_SYSTEM);
            channelPrepayAmountDTO.setOperator("系统");
            channelPrepayAmountDTO.setOrderId(orderWork.getOrderId());
            channelPrepayAmountDTO.setWorkId(orderWork.getWorkId());
            channelPrepayAmountDTO.setChannelPrepayAmount(payOrderDTO.getPayAmount());
            zsNormalMasterWorkBService.saveChannelPrepayAmountPay(channelPrepayAmountDTO);

        } else {
            orderWorkAmountService.deleteOriginalAmount(orderWork.getOrderId(), orderWork.getWorkId());
        }
    }

    /**
     * 渠道二次支付
     *
     * @param orderWork
     * @param payOrderDTO
     * @throws Exception
     */
    @SuppressWarnings("all")
    private void saveChannelSecondPay(OrderWork orderWork, PayOrderDTO payOrderDTO) throws Exception {

        ZsOrderPayDTO orderPayDTO = BeanMapper.map(payOrderDTO, ZsOrderPayDTO.class);
        orderPayDTO.setOrderId(orderWork.getOrderId());
        orderPayDTO.setWorkId(orderWork.getWorkId());

        // 插入渠道优惠 2021.12.14 by lhl
        if (NumberUtil.isNotNullOrZero(payOrderDTO.getDiscountAmount())) {
            AddDiscountDTO addDiscountDTO = new AddDiscountDTO();
            addDiscountDTO.setOrderId(orderWork.getOrderId());
            addDiscountDTO.setWorkId(orderWork.getWorkId());
            addDiscountDTO.setAmount(payOrderDTO.getDiscountAmount());
            addDiscountDTO.setDiscountUserName("系统");
            orderDiscountBService.channelDiscount(addDiscountDTO);
        }

        // 是否抵扣师傅收款额
        boolean subMasterAmount = Optional.ofNullable(payOrderDTO.getSubMasterAmount()).orElse(true);
        orderPayDTO.setSubMasterAmount(subMasterAmount);

        boolean completeOrder = Optional.ofNullable(payOrderDTO.getCompleteOrder()).orElse(true);
        if (completeOrder) {
            zsOrderPayBService.paySecondChannelPayAndOrderComplete(orderPayDTO);
            payOrderDTO.setOperatorRemark(null);
        }
        else {
            zsOrderPayBService.paySecondChannelPay(orderPayDTO);
        }
    }

    /**
     * 保存渠道数据
     *
     * @param orderId
     * @param outerData
     */
    private void saveOuterData(Long orderId, String outerData) {

        if (StringUtils.isBlank(outerData)) {
            return;
        }

        OrderExtend orderExtend = new OrderExtend();
        orderExtend.setExtId(orderId);
        orderExtend.setOuterData(outerData);
        orderExtendService.updateOrderExtend(orderExtend);
    }

    /**
     * 查找工单，并验证渠道信息
     *
     * @param orderId
     * @param channelId
     * @return
     * @throws OmsBaseException
     */
    private OrderWork validateChannelOrder( Long orderId, Integer channelId) throws OmsBaseException {

        OrderWork orderWork = orderWorkService.findOrderWorkByKey(orderId, orderId);
        if (Objects.isNull(orderWork)) {
            throw new OmsBaseException("订单不存在！");
        }

        if (NumberUtil.isNotNullOrZero(channelId) && !Objects.equals(orderWork.getChannelId(), channelId)) {
            throw new OmsBaseException("渠道订单不存在");
        }

        return orderWork;
    }

    /**
     * 添加日志
     *
     * @param orderWork
     * @param logType
     * @param logContent
     */
    private void saveOrderLog(OrderWork orderWork, Integer logType, String logContent) {

        // 设置缺省类型为渠道日志
        if (NumberUtil.isNullOrZero(logType)) {
            logType = OrderLogConsts.ORDER_LOG_TYPE_CHANNEL_REMARK;
        }

        OrderLog orderLog = new OrderLog();
        orderLog.setOrderId(orderWork.getOrderId());
        orderLog.setWorkId(orderWork.getWorkId());
        orderLog.setType(logType);
        orderLog.setTypeName(OrderLogConsts.getOrderLogTypeName(logType));
        orderLog.setBeforeStatus(orderWork.getStatus());
        orderLog.setBeforeStatusName(OrderStatusConsts.getWorkStatusName(orderWork.getStatus()));
        orderLog.setBeforeResultStatus(orderWork.getResultStatus());
        orderLog.setBeforeResultStatusName(OrderStatusConsts.getWorkResultStatusName(orderWork.getResultStatus()));
        orderLog.setAfterStatus(orderWork.getStatus());
        orderLog.setAfterStatusName(OrderStatusConsts.getWorkStatusName(orderWork.getStatus()));
        orderLog.setAfterResultStatus(orderWork.getResultStatus());
        orderLog.setAfterResultStatusName(OrderStatusConsts.getWorkResultStatusName(orderWork.getResultStatus()));
        orderLog.setContent(logContent);

        int operatorType = Objects.equals(logType, OrderLogConsts.ORDER_LOG_TYPE_CHANNEL_REMARK)
                ? GlobalConsts.OPERATE_USER_TYPE_CHANNEL
                : GlobalConsts.OPERATE_USER_TYPE_SYSTEM;
        orderLog.setOperator(GlobalConsts.getOperatorTypeName(operatorType));
        orderLog.setOperatorId((long)orderWork.getChannelId());
        orderLog.setOperatorType(operatorType);

        orderLogBService.save(orderLog);
    }

    /**
     * 新增订单埋点
     *
     * @param orderBO
     * @param omsBaseOperator
     */
    private void addOrderEventLog(OrderBO orderBO, OmsBaseOperator omsBaseOperator) {

        OrderWork orderWork = orderBO.getOrderWork();
        OrderDetail orderDetail = orderBO.getOrderDetail();
        List<OrderProduct> orderProductList = orderBO.getOrderProductList();
        OrderProduct orderProduct = orderProductList.get(0);
        final String site = "zmn-oms-api";

        AddOrderEventLogItem eventLogItem = new AddOrderEventLogItem();
        eventLogItem.setSite(site);
        eventLogItem.setBizId(String.valueOf(orderWork.getOrderId()));
        eventLogItem.setOrderId(String.valueOf(orderWork.getOrderId()));

        if (NumberUtil.isNotNullOrZero(orderProduct.getProductId())) {
            eventLogItem.setProductId(String.valueOf(orderProduct.getProductId()));
            eventLogItem.setProductName(orderProduct.getProductName());
        } else {
            eventLogItem.setProductId(String.valueOf(orderProduct.getShowProductId()));
            eventLogItem.setProductName(orderProduct.getShowProductName());
        }

        eventLogItem.setChannelId(String.valueOf(orderWork.getChannelId()));
        eventLogItem.setOrderChannelId(String.valueOf(orderWork.getChannelId()));
        eventLogItem.setSourceChannelId(String.valueOf(orderWork.getSourceChannelId()));
        eventLogItem.setLng(Objects.isNull(orderDetail.getLongitude()) ? "" : String.valueOf(orderDetail.getLongitude()));
        eventLogItem.setLat(Objects.isNull(orderDetail.getLatitude()) ? "" : String.valueOf(orderDetail.getLatitude()));

        DeviceLogItem deviceLogItem = new DeviceLogItem();
        if (Objects.nonNull(omsBaseOperator)) {
            deviceLogItem.setIp(omsBaseOperator.getIp());
        }

        EntryLogItem entryLogItem = new EntryLogItem();
        entryLogItem.setEntryType(String.valueOf(GateTypeConsts.GATE_TYPE_API));
        entryLogItem.setEntry(String.valueOf(GateTypeConsts.GATE_API_NORM));

        AddUserOperationLogRequest<AddOrderEventLogItem> request = new AddUserOperationLogRequest<>();
        request.setEntry(entryLogItem);
        request.setDevice(deviceLogItem);
        request.setEvent(eventLogItem);
        request.setClientName(site);

        try {
            logClient.addAddOrderEventLog(request);
        } catch (Exception e) {
            log.error("addOrderEventLog error：", e);
        }
    }

    /**
     * 修改用户电话 - xiewenbing 2020-05-29
     *
     * @param orderWork
     * @param userMobile
     */
    private void changeUserMobile(OrderWork orderWork,String userMobile) {

        log.info("修改订单用户电话，订单id:[{}]，电话:[{}]", orderWork.getOrderId(), userMobile);
        if (StringUtil.isBlank(userMobile)) {
            return;
        }

        // 获取原有的用户电话
        OrderDetail orderDetail = orderDetailService.findOrderDetailByKey(orderWork.getOrderId());
        if (Objects.isNull(orderDetail)) {
            return;
        }

        if (NumberUtil.isNullOrZero(orderWork.getUserId())) {

            Integer channelId = orderWork.getChannelId();

            // 根据入口判断是否为已登录状态
            boolean isRegisterUserCenter = (OrderConsts.LOGIN_ENTRANCE_LIST.contains(orderWork.getReceiveEntranceId()) && StringUtil.isMobile(orderDetail.getTelephone())) ||
                    (OrderConsts.LOGIN_CHANNEL_LIST.contains(channelId) && Objects.equals(orderWork.getInputType(), OrderConsts.ORDER_INPUT_TYPE_API));

            ResponseDTO<ChannelDRO> channelResponseDTO = channelListRemoteService.getByChannelId(channelId);
            ChannelDRO channelDRO = channelResponseDTO.getData();

            ResponseDTO<Long> responseDTO;
            // 通过电话注册用户
            if (isRegisterUserCenter) {
                // 登录状态 ucc创建用户
                UserRegisterByMobileNoCaptchaDIO userRegisterByMobileNoCaptchaDIO = new UserRegisterByMobileNoCaptchaDIO();
                userRegisterByMobileNoCaptchaDIO.setMobile(userMobile);
                userRegisterByMobileNoCaptchaDIO.setChannelId(channelId);
                userRegisterByMobileNoCaptchaDIO.setChannelName(channelDRO.getName());
                userRegisterByMobileNoCaptchaDIO.setPlat(orderWork.getPlat());
                userRegisterByMobileNoCaptchaDIO.setEntrance(NumberUtil.isNullOrZero(orderWork.getReceiveEntranceId()) ? GateTypeConsts.GATE_API_NORM : orderWork.getReceiveEntranceId());
                userRegisterByMobileNoCaptchaDIO.setNickName(orderDetail.getUserName());
                userRegisterByMobileNoCaptchaDIO.setOperator("系统");
                userRegisterByMobileNoCaptchaDIO.setOperatorId(Long.valueOf(channelId));
                log.debug("调用uuc创建用户入参，userRegisterDIO：{}", JSONObject.toJSONString(userRegisterByMobileNoCaptchaDIO));

                // 修改调用uuc接口  xiewenbing  2020-11-16
                responseDTO = userRegisterRemoteService.registerByMobileNoCaptcha(userRegisterByMobileNoCaptchaDIO);
                log.debug("调用uuc创建用户出参，userResponseDTO：{}，orderId：{}", JSONObject.toJSONString(responseDTO), orderWork.getOrderId());

            } else {
                // 未登录状态创建临时用户
                UserTempRegisterDIO userTempRegisterDIO = new UserTempRegisterDIO();
                userTempRegisterDIO.setGender(orderDetail.getGender());
                userTempRegisterDIO.setPlat(orderWork.getPlat());
                userTempRegisterDIO.setChannelId(channelId);
                userTempRegisterDIO.setChannelName(channelDRO.getName());
                userTempRegisterDIO.setEntrance(NumberUtil.isNullOrZero(orderWork.getReceiveEntranceId()) ? GateTypeConsts.GATE_API_NORM : orderWork.getReceiveEntranceId());
                userTempRegisterDIO.setNickName(FilterUtil.replaceSpeChar(StringUtils.defaultString(orderDetail.getUserName())));
                userTempRegisterDIO.setOperator("系统");
                userTempRegisterDIO.setOperatorId(Long.valueOf(channelId));
                log.debug("调用uuc创建临时用户入参，userRegisterDIO：{} ", JSONObject.toJSONString(userTempRegisterDIO));

                // 修改调用uuc接口  xiewenbing  2020-11-16
                responseDTO = userRegisterRemoteService.registerTempUser(userTempRegisterDIO);
                log.debug("调用uuc创建临时用户出参，userResponseDTO：{}，orderId：{}", JSONObject.toJSONString(responseDTO), orderWork.getOrderId());

            }

            log.info("通过电话注册用户，电话：[{}]，结果：[{}]", userMobile, responseDTO.isSuccess() ? "success" : "failed");

            if (responseDTO.isSuccess()) {

                OrderWork updateOrderWork = new OrderWork();
                updateOrderWork.setOrderId(orderWork.getOrderId());
                updateOrderWork.setWorkId(orderWork.getWorkId());
                updateOrderWork.setUserId(responseDTO.getData());

                orderWorkService.updateOrderWorkByKey(updateOrderWork);
            }

        } else {

            // 修改用户电话 - uuc接口  xiewenbing  2020-11-16
            ResponseDTO responseDTO = userModifyRemoteService.modifyPhoneByUserId(orderWork.getUserId(), userMobile);
            log.info("修改用户电话，用户id：[{}]，新电话：[{}]，原有电话：[{}],结果：[{}]", orderWork.getUserId(), userMobile, orderDetail.getTelephone(),
                    responseDTO.isSuccess() ? "success" : "failed");
            if (responseDTO.isSuccess()) {
                return;
            }

            // 失败可能是已经注册了，根据电话查找并重新设置工单的用户id
            UserMobilePlatQuery userMobilePlatQuery = new UserMobilePlatQuery();
            userMobilePlatQuery.setPlat(orderWork.getPlat());
            userMobilePlatQuery.setIsSensitive(Boolean.FALSE);
            userMobilePlatQuery.setMobile(userMobile);
            ResponseDTO<UserBaseDRO> userResponseDTO = userListRemoteService.getMajorUserByMobileAndPlat(userMobilePlatQuery);
            if (!userResponseDTO.isSuccess()) {
                return;
            }

            OrderWork updateOrderWork = new OrderWork();
            updateOrderWork.setOrderId(orderWork.getOrderId());
            updateOrderWork.setWorkId(orderWork.getWorkId());
            updateOrderWork.setUserId(userResponseDTO.getData().getUserId());

            orderWorkService.updateOrderWorkByKey(updateOrderWork);
        }
    }

    /**
     * 获得订单的备注信息
     *
     * @param orderId
     * @param workId
     * @param remarkType
     * @return
     */
    @Override
    public String queryOrderRemark(Long orderId, Long workId, Integer remarkType) throws OmsBaseException {

        OrderRemarkVO orderRemarkVO = orderRemarkBService.findOrderRemarkVO(orderId, workId,remarkType);

        if (Objects.isNull(orderRemarkVO)) {
            return "";
        }

        if (StringUtils.isNotBlank(orderRemarkVO.getContent())) {
            return orderRemarkVO.getContent();
        }

        List<OrderRemarkDetailVO> detailVOList = orderRemarkVO.getDetailVOList();
        if (CollectionUtil.isNullOrEmpty(detailVOList)) {
            return "";
        }

        return detailVOList.get(0).getMapName();
    }
}
